<template>
  <el-dialog :close-on-click-modal='false' v-drag :title="record.rule_id ? $t('编辑') : $t('添加')" append-to-body :v-if="dialogVisible" :visible.sync="dialogVisible" :width="dialogWidth" top="5vh" @close='close'>
    <div class="dialogContentBoxMaxHeight90">
      <el-form ref="form" :model="record" :inline="true" label-width="120px" :rules="rules" label-position="left" style="margin:0 30px;">
        <el-form-item :label="$t('协议名称')" class="s7300Form" prop="proto">
          <div style="color:#999;width:250px;">{{ rule[record.proto] }}</div>
        </el-form-item>
        <el-form-item :label="$t('类型')" prop="operate_type">
          <el-radio-group v-model="record.operate_type" :disabled='record.rule_id ? true : false' @change="operateTypeChange">
            <el-radio :label="0" class="deepfilts">{{$t('深度过滤')}}</el-radio>
            <el-radio :label="1" class="operate">{{$t('关联操作')}}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item :label="$t('动作')" class="s7300Form" prop="action">
          <el-select v-model="record.action" size='small' ref="action" style="width:250px;" filterable>
            <el-option v-for="(value, key) in actionList" :key="key" :label="$t(value)" :value="key">
            </el-option>
          </el-select>
        </el-form-item>
        <div v-if="record.operate_type === 0">
          <el-form-item :label="$t('功能码')" class="s7300Form" prop="ruleType">
            <el-select v-model="record.func" size='small' ref="func" style="width:250px;" filterable @change="ruleTypeChange">
              <el-option v-for="(value, key) in funcList" :key="value" :label="$t(value)" :value="key">
              </el-option>
            </el-select>
          </el-form-item>
          <div v-if="showOther.includes(record.func)">
            <el-form-item :label="$t('匹配范围')" class="s7300Form" prop="action">
              <el-radio-group v-model="record.accept_range">
                <el-radio label="all" class="all">{{$t('所有')}}</el-radio>
                <el-radio label="single" class="single">{{$t('单个')}}</el-radio>
              </el-radio-group>
            </el-form-item>
            <div class="strategyFatherBox" v-if="record.accept_range === 'single'">
              <el-button type="success" size='small' style="margin-bottom:10px;" class="addFunc" @click="addConfig(record.func)">{{$t('添加配置')}}</el-button>
              <el-table ref="multipleTable" border :data="record.rows" tooltip-effect="dark" size='mini'>
                <el-table-column prop="register_interval" align='center' :formatter="registerIntervalFormatter" :label="$t('寄存器区间')" />
                <el-table-column prop="register_address_range" align='center' :formatter="registerAddressFormatter" min-width="120" :label="$t('寄存器范围地址')" />
                <el-table-column prop="db_num" align='center' :label="$t('DB值')" />
                <el-table-column prop="register_value_type" align='center' :label="$t('寄存器值类型')">
                  <template slot-scope="scope">
                    <tooltip :html="registerValueTypeFormatter(scope.row)" :content="registerValueTypeFormatter(scope.row)" class="wid190" :refName="scope.row.name">
                    </tooltip>
                  </template>
                </el-table-column>
                <el-table-column prop="register_value_range" align='center' :formatter="registerValueRangeFormatter" :label="$t('寄存器值范围')">
                  <template slot-scope="scope">
                    <tooltip :html="registerValueRangeFormatter(scope.row)" :content="registerValueRangeFormatter(scope.row)" class="wid190" :refName="scope.row.name">
                    </tooltip>
                  </template>
                </el-table-column>
                <el-table-column align="center" :label="$t('操作')" width="100" fixed='right'>
                  <template slot-scope="scope">
                    <el-button type="danger" plain @click="deleteRule(scope.row)" size='mini'>{{$t('删除')}}</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
        <div v-if="record.operate_type === 1">
          <el-form-item :label="$t('写寄存器区间')" class="opcForm" prop="relate_write_register_interval" key="relate_write_register_interval">
            <el-select v-model="record.relate_write_register_interval" ref="interval" class="s7300Length" size='small' filterable>
              <el-option v-for="(value, key) in intervalList" :key="key" :label="$t(value)" :value="key">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('写db值')" prop="write_db_num" v-if="showDbNumList.includes(record.relate_write_register_interval)">
            <el-input v-emoji v-model="record.write_db_num" ref="nums" class="s7300Length" size='small'></el-input>
          </el-form-item>
          <el-form-item :label="$t('写寄存器地址')" class="opcForm" prop="write_register_address_range" key="write_register_address_range">
            <el-input v-emoji v-model="record.write_register_address_range" ref="ranges" :maxlength="128" :style="'width:' + (showPositionList.includes(record.relate_write_register_interval) ? '150px' : '250px')" size='small'></el-input>
          </el-form-item>
          <el-form-item label-width="0" v-if="showPositionList.includes(record.relate_write_register_interval)" prop="write_register_address_range_position">
            {{$t('位')}} <el-select v-model="record.write_register_address_range_position" ref="rangePosition" style="width:70px" size='small'>
              <el-option v-for="val in positionList" :key="val" :label="val" :value="val">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label-width="0" v-if="showPositionList.includes(record.register_interval)" prop="register_address_start_position">
            {{$t('位')}} <el-select v-model="record.register_address_start_position" ref='startPosition' style="width:70px" size='small'>
              <el-option v-for="val in positionList" :key="val" :label="val" :value="val">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('读寄存器区间')" class="opcForm" prop="relate_read_register_interval" key="relate_read_register_interval">
            <el-select v-model="record.relate_read_register_interval" ref="registerInterval" class="s7300Length" size='small' filterable>
              <el-option v-for="(value, key) in intervalList" :key="key" :label="$t(value)" :value="key">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('读db值')" prop="read_db_num" v-if="showDbNumList.includes(record.relate_read_register_interval)">
            <el-input v-emoji v-model="record.read_db_num" ref="dbNum" class="s7300Length" size='small'></el-input>
          </el-form-item>
          <el-form-item :label="$t('读寄存器地址')" class="opcForm" prop="read_register_address_range" key="read_register_address_range">
            <el-input v-emoji v-model="record.read_register_address_range" ref="range" :maxlength="128" :style="'width:' + (showPositionList.includes(record.relate_read_register_interval) ? '150px' : '250px')" size='small'></el-input>
          </el-form-item>
          <el-form-item label-width="0" v-if="showPositionList.includes(record.relate_read_register_interval)" prop="read_register_address_range_position">
            {{$t('位')}} <el-select v-model="record.read_register_address_range_position" ref="rangePositions" style="width:70px" size='small'>
              <el-option v-for="val in positionList" :key="val" :label="val" :value="val">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label-width="0" v-if="showPositionList.includes(record.register_interval)" prop="register_address_start_position">
            {{$t('位')}} <el-select v-model="record.register_address_start_position" ref="startPositions" style="width:70px" size='small'>
              <el-option v-for="val in positionList" :key="val" :label="val" :value="val">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('读寄存器值类型')" class="opcForm" prop="read_register_value_type">
            <el-select v-model="record.read_register_value_type" ref="valueType" class="s7300Length" size='small' filterable @change="registerValueTypeChange">
              <el-option v-for="(value, key) in valueTypeReList" :key="key" :label="$t(value)" :value="key">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('读寄存器值范围')" prop="register_value_range_select" v-if="showSelectList.includes(record.read_register_value_type)" key="register_value_range_select">
            <el-select v-model="record.register_value_range_select" ref="rangeSelect" class="s7300Length" @change="registerRangeChange" size='small' filterable>
              <el-option v-for="(value, key) in rangeList" :key="key" :label="$t(value)" :value="key">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('读寄存器值范围')" prop="register_value_range_start" style="margin-right:0" v-if="!showSelectNullList.includes(record.read_register_value_type)" key="register_value_range_start">
            <el-input v-emoji v-model="record.register_value_range_start" ref="start" :maxlength="100" @change="registerRangeChange" style="width:117px" size='small'></el-input>
          </el-form-item>
          <el-form-item label="" v-if="!showSelectNullList.includes(record.read_register_value_type)" style="margin-right:0">~</el-form-item>
          <el-form-item label-width="0" v-if="!showSelectNullList.includes(record.read_register_value_type)" prop="register_value_range_end" key="register_value_range_end">
            <el-input v-emoji v-model="record.register_value_range_end" ref="end" :maxlength="100" @change="registerRangeChange" style="width:117px" size='small'></el-input>
          </el-form-item>
        </div>
      </el-form>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submit" class="innerAddSubmit">{{$t('确 定')}}</el-button>
      <el-button @click="close" class="innerAddClose">{{$t('取 消')}}</el-button>
    </span>

    <add-config-dialog v-if="addConfigDialog" ref="RefAddConfigDialog" @addConfigRows='addConfigRows'></add-config-dialog>
  </el-dialog>
</template>
<script>
import ruleArray from '../../ruleArray'
import AddConfigDialog from './AddConfigDialog.vue'
import { inputClass, selectClass } from '@/utils/input-class.js'
export default {
  components: { AddConfigDialog },
  name: 'S7300Dialog',
  data () {
    var validateName = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')))
      } else {
        callback()
      }
    }
    var validateDbNum = (rule, value, callback) => {
      if (value === '') {
        callback()
      } else if (!this.isInteger(value)) {
        callback(new Error(this.$t('只能输入整数')))
      } else if (Number(value) < 0 || Number(value) > 256) {
        callback(new Error(this.$t('输入范围0~256')))
      } else {
        callback()
      }
    }
    var validateRangeStart = (rule, value, callback) => {
      if (value === '') {
        callback()
      } else if (!this.isInteger(value)) {
        callback(new Error(this.$t('只能输入整数')))
      } else if ((Number(value) < 0 || Number(value) > 65535) && this.record.read_register_value_type !== '5') {
        callback(new Error(this.$t('输入范围0~65535')))
      } else if ((Number(value) < -32768 || Number(value) > 32768) && this.record.read_register_value_type === '5') {
        callback(new Error(this.$t('范围-32768~32768')))
      } else if (this.record.register_value_range_start && this.record.register_value_range_end && (Number(this.record.register_value_range_start) > Number(this.record.register_value_range_end))) {
        callback(new Error(this.$t('必须小于最大值')))
      } else {
        this.chearRule('register_value_range_start')
        this.chearRule('register_value_range_end')
        callback()
      }
    }
    var validateRangeEnd = (rule, value, callback) => {
      if (value === '') {
        callback()
      } else if (!this.isInteger(value)) {
        callback(new Error(this.$t('只能输入整数')))
      } else if ((Number(value) < 0 || Number(value) > 65535) && this.record.read_register_value_type !== '5') {
        callback(new Error(this.$t('输入范围0~65535')))
      } else if ((Number(value) < -32768 || Number(value) > 32768) && this.record.read_register_value_type === '5') {
        callback(new Error(this.$t('范围-32768~32768')))
      } else if (this.record.register_value_range_start && this.record.register_value_range_end && (Number(this.record.register_value_range_start) > Number(this.record.register_value_range_end))) {
        callback(new Error(this.$t('必须大于最小值')))
      } else {
        this.chearRule('register_value_range_start')
        this.chearRule('register_value_range_end')
        callback()
      }
    }
    return {
      dialogVisible: false,
      addConfigDialog: false,
      dialogWidth: '500px',
      record: {
        accept_range: 'all',
        action: 'accept',
        func: '0x00',
        proto: 's7_300',
        rule_id: null,
        operate_type: 0,
        rows: [],
        relate_write_register_interval: 'P',
        write_db_num: '',
        write_register_address_range: '',
        write_register_address_range_position: '0',
        relate_read_register_interval: 'P',
        read_db_num: '',
        read_register_address_range: '',
        read_register_address_range_position: '0',
        read_register_value_type: '0',
        register_value_range_select: '0',
        register_value_range_start: '',
        register_value_range_end: '',
        read_register_value_range: ''
      },
      recordCopy: {
        accept_range: 'all',
        action: 'accept',
        func: '0x00',
        proto: 's7_300',
        rule_id: null,
        operate_type: 0,
        rows: [],
        relate_write_register_interval: 'P',
        write_db_num: '',
        write_register_address_range: '',
        write_register_address_range_position: '0',
        relate_read_register_interval: 'P',
        read_db_num: '',
        read_register_address_range: '',
        read_register_address_range_position: '0',
        read_register_value_type: '0',
        register_value_range_select: '0',
        register_value_range_start: '',
        register_value_range_end: '',
        read_register_value_range: ''
      },
      rule: ruleArray.ruleShow,
      funcList: ruleArray.code,
      intervalList: ruleArray.intervalList,
      valueTypeReList: ruleArray.valueTypeReList,
      valueTypeList: ruleArray.valueTypeList,
      rangeList: ruleArray.rangeList,
      // showPositionList: ['I', 'Q', 'M', 'DB'],
      actionList: { 'accept': '允许', 'alert': '告警' },
      showOther: ['0x04', '0x05'],
      showSelectList: ['3'],
      showSelectNullList: ['3', '0'],
      showPositionList: ['I', 'Q', 'M', 'DB', 'DI'],
      showDbNumList: ['DB', 'DI'],
      positionList: ['0', '1', '2', '3', '4', '5', '6', '7'],
      rules: {
        write_register_address_range: [{ required: false, validator: validateName, trigger: 'blur' }],
        read_register_address_range: [{ required: false, validator: validateName, trigger: 'blur' }],
        write_db_num: [{ required: false, validator: validateDbNum, trigger: 'blur' }],
        read_db_num: [{ required: false, validator: validateDbNum, trigger: 'blur' }],
        register_value_range_start: [{ required: false, validator: validateRangeStart, trigger: 'blur' }],
        register_value_range_end: [{ required: false, validator: validateRangeEnd, trigger: 'blur' }]

      }
    }
  },
  computed: {
    change () {
      const { operate_type, relate_write_register_interval, relate_read_register_interval } = this.record
      return { operate_type, relate_write_register_interval, relate_read_register_interval }
    }
  },
  watch: {
    change (val) {
      if (val.operate_type === 1) {
        if (this.showPositionList.includes(val.relate_write_register_interval)) {
          this.$nextTick(() => {
            const selectData = ['rangePosition']
            selectClass(this.$refs, selectData)
            inputClass(this.$refs, ['nums'])
          })
        }
        if (this.showPositionList.includes(val.relate_read_register_interval)) {
          this.$nextTick(() => {
            const selectData = ['rangePositions']
            inputClass(this.$refs, ['dbNum'])
            selectClass(this.$refs, selectData)
          })
        }
      }
    },
    'record.accept_range': {
      handler (val) {
        if (val === 'single' && this.record.operate_type === 0) {
          this.dialogWidth = '800px'
        } else {
          this.dialogWidth = '500px'
        }
      }
    },
    'record.operate_type': {
      handler (val) {
        if (val === 1) {
          this.dialogWidth = '500px'
          this.$nextTick(() => {
            const data = ['ranges', 'range', 'start', 'end']
            const selectData = ['interval', 'valueType', 'registerInterval']
            selectClass(this.$refs, selectData)
            inputClass(this.$refs, data)
          })
        } else if (val === 0 && this.record.accept_range === 'single') {
          this.dialogWidth = '800px'
        }
      }
    }
  },
  methods: {
    init (data) {
      this.dialogVisible = true
      this.$nextTick(() => {
        const selectData = ['action', 'func']
        selectClass(this.$refs, selectData)
      })
      if (data) {
        this.record = Object.assign(this.record, data)
      }
    },
    ruleTypeChange (type) {
      this.record.rows = []
      if (!this.showOther.includes(type)) {
        this.record.accept_range = 'all'
        this.dialogWidth = '500px'
      }
    },
    submit () {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.record.rows.length < 1 && this.showOther.includes(this.record.func) && this.record.accept_range === 'single' && this.record.operate_type === 0) {
            this.$messages.error(this.$t('请添加配置'))
          } else if ((this.record.register_value_range_start && !this.record.register_value_range_end) || (!this.record.register_value_range_start && this.record.register_value_range_end)) {
            this.$messages.error(this.$t('读寄存器值范围填写错误'))
          } else {
            var formData = JSON.parse(JSON.stringify(this.record))
            if (formData.accept_range === 'all') {
              formData.rows = []
            }
            this.$emit('addConfigRuleMap', formData)
          }
        }
      })
    },
    close () {
      this.dialogVisible = false
      this.$emit('childrenClose')
      this.dialogWidth = '500px'
      this.record = Object.assign({}, this.recordCopy)
      if (this.record.accept_range === 'single') {
        this.$refs.multipleTable.clearSelection()
      }
      this.$refs.form.resetFields()
    },
    // 添加规则按钮
    addConfig (data) {
      this.addConfigDialog = true
      this.$nextTick(() => {
        this.$refs.RefAddConfigDialog.init(data)
      })
    },
    addConfigRows (data) {
      this.record.rows.push(data)
      this.ruleIdChange()
    },
    registerIntervalFormatter (data) {
      return this.intervalList[data.register_interval]
    },
    registerAddressFormatter (data) {
      if (this.showPositionList.includes(data.register_interval)) {
        return data.register_address_start + '.' + data.register_address_start_position + '-' + data.register_address_end + '.' + data.register_address_end_position
      } else {
        return data.register_address_start + '-' + data.register_address_end
      }
    },
    registerValueTypeFormatter (data) {
      if (data.register_value_type !== null && this.record.func !== 4 && this.record.func !== '0x04') { // 如果是读寄存器就没有寄存器范围
        return this.valueTypeList[data.register_value_type]
      }
    },
    registerValueRangeFormatter (data) {
      if (this.record.func === 4 || this.record.func === '0x04') { // 如果是读寄存器就没有寄存器范围
        return
      }
      if (['3'].includes(data.register_value_type)) {
        return this.rangeList[data.register_value_range_select]
      } else {
        return data.register_value_range_start + '-' + data.register_value_range_end
      }
      // if (data.register_value_range_start !== '') {
      //   if (data.register_value_range_end !== '') {
      //     return data.register_value_range_start + '-' + data.register_value_range_end
      //   } else {
      //     return this.rangeList[data.register_value_range_start]
      //   }
      // }
    },
    deleteRule (row) {
      this.record.rows.splice(row.rule_id - 1, 1)
      this.ruleIdChange()
    },
    // 重新分配规则id
    ruleIdChange () {
      this.record.rows.forEach((tab, index) => {
        tab.rule_id = index + 1
      })
    },
    operateTypeChange (data) {
      this.record.proto = data === 0 ? 's7_300' : 's7_300_connect'
    },
    registerRangeChange () {
      if (this.showSelectList.includes(this.record.read_register_value_type)) {
        this.record.read_register_value_range = this.record.register_value_range_select + '~' + this.record.register_value_range_select
      } else if (this.record.register_value_range_start || this.record.register_value_range_end) {
        this.record.read_register_value_range = this.record.register_value_range_start + '~' + this.record.register_value_range_end
      } else {
        this.record.read_register_value_range = ''
      }
    },
    registerValueTypeChange () {
      this.record.register_value_range_start = ''
      this.record.register_value_range_end = ''
      this.record.register_value_range_select = '0'
      this.$refs['form'].clearValidate(['register_value_range_select', 'register_value_range_start', 'register_value_range_end'])
      this.registerRangeChange()
    },
    isInteger (value) {
      return (!isNaN(value) && (parseInt(value).toString().length === String(Number(value)).length))
    },
    chearRule (name) {
      if (!isNaN(Number(this.record[name])) && this.isInteger(this.record[name]) && (Number(this.record[name]) >= 0 && Number(this.record[name]) <= 65535)) {
        this.$refs['form'].clearValidate([name])
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.s7300Form {
  width: 400px;
}

.s7300Length {
  width: 250px;
}
</style>
